package com.btcode.web.safe.filter;

import com.btcode.common.MyLog;
import com.btcode.log.ILog;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class XSSCheckFilter implements Filter {

    private ILog log;

    private static String[] excludePaths;// 不进行拦截的url

    private static String[] safeless = {
        "<script", // 需要拦截的JS字符关键字
        "</script", "<iframe", "</iframe", "<frame", "</frame", "set-cookie", "%3cscript",
        "%3c/script", "%3ciframe", "%3c/iframe", "%3cframe", "%3c/frame", "src=\"javascript:",
        "<body", "</body", "%3cbody", "%3c/body"
    };

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)
        throws IOException, ServletException {
        Enumeration<String> params = req.getParameterNames();
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        boolean isSafe = true;
        String requestUrl = request.getRequestURI();
        if (isSafe(requestUrl)) {
            requestUrl = requestUrl.substring(requestUrl.indexOf("/"));
            if (!excludeUrl(requestUrl)) {
                while (params.hasMoreElements()) {
                    String cache = req.getParameter((String) params.nextElement());
                    if (null != cache && cache.length() > 0) {
                        if (!isSafe(cache)) {
                            isSafe = false;
                            break;
                        }
                    }
                }
            }
        }
        else {
            isSafe = false;
        }

        if (!isSafe) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("{\"msg\":\"非法参数\"}");
            response.getWriter().flush();
            log.info(requestUrl + ",地址有非法参数");
            return;
        }
        filterChain.doFilter(req, resp);
    }

    private static boolean isSafe(String str) {
        if (null != str && str.length() > 0) {
            for (String s : safeless) {
                if (str.toLowerCase().contains(s)) {
                    return false;
                }
            }
        }
        return true;
    }

    private boolean excludeUrl(String url) {
        if (excludePaths != null && excludePaths.length > 0) {
            for (String path : excludePaths) {
                if (url.toLowerCase().equals(path)) {
                    return true;
                }
            }
        }
        return false;
    }

    public void destroy() {
    }

    public void init(FilterConfig config) throws ServletException {
        log = MyLog.getInstance().getLogger(getClass());
    }
}
